<script setup lang="ts">
import { computed } from 'vue';
import { defu } from 'defu';
import { useThemeStore } from '@/store/modules/theme';
import { themeSettings } from '@/theme/settings';
import { $t } from '@/locales';

defineOptions({
  name: 'ThemePreset'
});

type ThemePreset = Pick<
  App.Theme.ThemeSetting,
  | 'themeScheme'
  | 'grayscale'
  | 'colourWeakness'
  | 'recommendColor'
  | 'themeColor'
  | 'themeRadius'
  | 'otherColor'
  | 'isInfoFollowPrimary'
  | 'layout'
  | 'page'
  | 'header'
  | 'tab'
  | 'fixedHeaderAndTab'
  | 'sider'
  | 'footer'
  | 'watermark'
  | 'tokens'
> & {
  name: string;
  desc: string;
  i18nkey?: string;
  version: string;
  sort: number;
  /** Optional NaiveUI theme overrides */
  naiveui?: App.Theme.NaiveUIThemeOverride;
};

const presetModules = import.meta.glob('@/theme/preset/*.json', { eager: true, import: 'default' });

const themeStore = useThemeStore();

// Extract preset data
const presets = computed(() =>
  Object.entries(presetModules)
    .map(([path, presetData]) => {
      const fileName = path.split('/').pop()?.replace('.json', '') || '';
      return {
        id: fileName,
        ...(presetData as ThemePreset)
      };
    })
    .sort((a, b) => {
      return (a.sort ?? 0) - (b.sort ?? 0);
    })
);

const getPresetName = (preset: ThemePreset): string => {
  if (!preset.i18nkey) return preset.name;
  try {
    const key = `${preset.i18nkey}.name` as App.I18n.I18nKey;
    const translated = $t(key);
    return translated !== key ? translated : preset.name;
  } catch {
    return preset.name;
  }
};

const getPresetDesc = (preset: ThemePreset): string => {
  if (!preset.i18nkey) return preset.desc;
  try {
    const key = `${preset.i18nkey}.desc` as App.I18n.I18nKey;
    const translated = $t(key);
    return translated !== key ? translated : preset.desc;
  } catch {
    return preset.desc;
  }
};

const applyPreset = (preset: ThemePreset): void => {
  const mergedPreset = defu(preset, themeSettings);
  const { themeScheme, grayscale, colourWeakness, layout, watermark, naiveui, ...rest } = mergedPreset;
  themeStore.setThemeScheme(themeScheme);
  themeStore.setGrayscale(grayscale);
  themeStore.setColourWeakness(colourWeakness);
  themeStore.setThemeLayout(layout.mode);
  themeStore.setWatermarkEnableUserName(watermark.enableUserName);
  themeStore.setWatermarkEnableTime(watermark.enableTime);

  Object.assign(themeStore, {
    ...rest,
    layout: { ...themeStore.layout, scrollMode: layout.scrollMode },
    page: { ...rest.page },
    header: { ...rest.header },
    tab: { ...rest.tab },
    sider: { ...rest.sider },
    footer: { ...rest.footer },
    watermark: { ...watermark },
    tokens: { ...rest.tokens }
  });

  // Apply NaiveUI theme overrides if present
  themeStore.setNaiveThemeOverrides(naiveui);

  window.$message?.success($t('theme.appearance.preset.applySuccess'));
};
</script>

<template>
  <NDivider>{{ $t('theme.appearance.preset.title') }}</NDivider>

  <div class="flex flex-col gap-3">
    <div
      v-for="preset in presets"
      :key="preset.id"
      class="border border-primary/10 rounded-lg border-solid bg-white/5 p-3 backdrop-blur-10 transition-all duration-300 hover:(shadow-md -translate-y-0.5)"
    >
      <div class="mb-2 flex items-center justify-between">
        <div class="min-w-0 w-full flex flex-1 items-center justify-between gap-2">
          <h5 class="m-0 truncate text-sm text-primary font-600">
            {{ getPresetName(preset) }}
          </h5>
          <NBadge :value="`v${preset.version}`" type="info" size="small" class="flex-shrink-0 opacity-80" />
        </div>
        <NButton type="primary" size="tiny" ghost round class="ml-2 flex-shrink-0" @click="applyPreset(preset)">
          {{ $t('theme.appearance.preset.apply') }}
        </NButton>
      </div>

      <p class="line-clamp-2 mb-3 text-xs text-gray-500 leading-4">{{ getPresetDesc(preset) }}</p>

      <div class="flex items-center justify-between">
        <div class="flex gap-1">
          <div
            v-for="(color, key) in { primary: preset.themeColor, ...preset.otherColor }"
            :key="key"
            class="h-3 w-3 cursor-pointer border border-white/30 rounded-full transition-transform hover:scale-110"
            :style="{ backgroundColor: color }"
            :class="{ 'ring-1 ring-primary/50': key === 'primary' }"
            :title="key"
          />
        </div>
        <div class="flex items-center gap-1">
          <div class="text-lg">
            {{ preset.themeScheme === 'dark' ? '🌙' : '☀️' }}
          </div>
          <div class="text-lg">
            {{ preset.grayscale ? '🎨' : '' }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
